#include "Sprite.h"
#include "GameDeviceSingleton.h"
#include "ViewPort.h"


Sprite::Sprite(LPD3DXSPRITE SpriteHandler, int fileName, bool repeat)
{
	_Inititialize(SpriteHandler, fileName, repeat);
}

Sprite::Sprite(LPD3DXSPRITE SpriteHandler, int fileName, bool repeat, int framerate)
{
	_Inititialize(SpriteHandler, fileName, repeat);
	setDelay(framerate);
}

void Sprite::_Inititialize(LPD3DXSPRITE SpriteHandler, int fileName, bool repeat)
{
	_SpriteHandler = SpriteHandler;

	LPDIRECT3DDEVICE9 d3ddv;
	SpriteHandler->GetDevice(&d3ddv);

	_texture = TextureManager::getInstance(d3ddv)->getTexture(fileName);

	_Index = 0;
	_IndexStart = 0;
	_IndexEnd = _texture->Count;
	_repeat = repeat;
	_endOfSheet = false;
	_counter = 0;
}

void Sprite::setIndex(int index) {
	this->_Index = index;
}

Sprite::Sprite(LPD3DXSPRITE SpriteHandler, int fileName) 
{
	_Inititialize(SpriteHandler, fileName, false);
}

void Sprite::Render(double X, double Y)
{
	this->Render(NULL,X,Y);
}

void Sprite::Render(LPDIRECT3DSURFACE9 Target, double X, double Y)
{
	Render(Target, X, Y, 255);
}

void Sprite::RenderNonTransform(double X, double Y) {
	D3DXVECTOR3 position(X, Y, 0);
	srect.left = (_Index % this->_texture->PerRow) * _texture->Width + 1;
	srect.top =  (_Index / this->_texture->PerRow) * _texture->Height;
	srect.right = srect.left + _texture->Width - 1;
	srect.bottom = srect.top + _texture->Height;

	_SpriteHandler->Draw(
		_texture->Image,
		&srect,
		&D3DXVECTOR3(_texture->Width / 2, _texture->Height / 2, 0),
		&position,
		D3DCOLOR_ARGB(255,255,255,255));
}

void Sprite::Render(LPDIRECT3DSURFACE9 Target, double X, double Y, int alpha)
{
	srect.left = (_Index % this->_texture->PerRow) * _texture->Width + 1;
	srect.top =  (_Index / this->_texture->PerRow) * _texture->Height;
	srect.right = srect.left + _texture->Width - 1;
	srect.bottom = srect.top + _texture->Height;
	/*srect.left = (_Index % _texture->PerRow)*(_texture->Width) + 1;
	srect.top = (_Index / _texture->PerRow)*(_texture->Height) + 1;
	srect.right = srect.left + _texture->Width;
	srect.bottom = srect.top + _texture->Height + 1;*/

	CViewPort* viewport = GameDeviceSingleton::getInstance()->getViewPort();

	D3DXMATRIX idenMatrix;
	D3DXMatrixIdentity(&idenMatrix);
	idenMatrix._22=-1;
	D3DXVECTOR4 vppos;
	D3DXVECTOR3 temp(-viewport -> getLeft() + X, -viewport->getBottom()  + Y,(float)0);
	D3DXVec3Transform(&vppos,&temp,&idenMatrix);

	D3DXVECTOR3 position((float)vppos.x - (_texture->Width - 2)/2, (float)vppos.y - _texture->Height/2, 0);

	_SpriteHandler->Draw(
		_texture->Image,
		&srect,
		NULL,
		&position,
		D3DCOLOR_ARGB(alpha,255,255,255));
}

int Sprite::currentIndex() {
	return _Index;
}

void Sprite::Render(LPDIRECT3DSURFACE9 Target, D3DXMATRIX *matrix, double X, double Y)
{	
	srect.left = (_Index % _texture->PerRow)*(_texture->Width)+1;
	srect.top = (_Index / _texture->PerRow)*(_texture->Height)+1;
	srect.right = srect.left + _texture->Width ;
	srect.bottom = srect.top + _texture->Height +1;

	viewPos3.x = X;
	viewPos3.y = Y;
	viewPos3.z = 0;
	_getViewPos3(&viewPos3, matrix);
	_SpriteHandler->Draw(
		_texture->Image,
		&srect, 
		&D3DXVECTOR3(_texture->Width / 2, _texture->Height / 2, 0),
		&viewPos3,//position, 
		D3DCOLOR_XRGB(255,255,255)
		);
}

void Sprite::setStartEnd(int start, int end)
{
	if (_Index < start) _Index = start;
	_IndexStart = start - 1;
	_IndexEnd = end;
}

void Sprite::setDelay(int delay)
{
	_delay = delay;
}

void Sprite::setToEnd() {
	_Index = _IndexEnd - 1;
}

void Sprite::setToStart() {
	this->setIndex(getStartIndex());
}

int Sprite::getDelay() {
	return _delay;
}

void Sprite::Next() 
{
	_counter++;
	_endOfSheet = false;
	if (_counter < _delay)
		return;
	else
		_counter = 0;
	if (_isActive)
	{
		_endOfSheet = false;
		_Index = _IndexStart;
		_isActive = false;
	}
	else
	{
		_Index++;
	}
	if (_Index > _IndexEnd)
	{
		if (_repeat)
			_Index = _IndexStart;
		else
			_Index--; 
	}
	else if (_Index == _IndexEnd - 1) {
		_endOfSheet = true;
	}
	_Index = (_Index) % (_IndexEnd);
	if (_Index < _IndexStart) _Index = _IndexStart + 1;
}

int Sprite::getStartIndex() {
	return _IndexStart;	
}

void Sprite::setNoneEnd() {
	_endOfSheet = false;
}

void Sprite::setToOver() {
	_Index = _IndexEnd + 1;
}

void Sprite::active()
{
	if (endOfSheet()) {
		_isActive = true;
	}
	else
		_isActive = false;
	Next();
}

bool Sprite::endOfSheet()
{
 	return _Index == _IndexEnd - 1;
}

void Sprite::setIndexEnd(int indexEnd) {
	this->_IndexEnd = indexEnd;
}

void Sprite::Reset()
{
	_Index = _IndexStart;
	_endOfSheet = false;
}

Sprite::~Sprite()
{
	//delete _texture;
}

void Sprite::destroy() {
}

void Sprite::_getViewPos3(D3DXVECTOR3* position, D3DXMATRIX* matrix) {
	D3DXVec3Transform(&viewPos4, position, matrix);
	viewPos3.x = viewPos4.x;
	viewPos3.y = viewPos4.y;
	viewPos3.z = 0;
}